#ifndef UNI_MESH_HPP
#define UNI_MESH_HPP

#include "structMeshBase.hpp"
#include "uniEdge.hpp"
#include "uniEdges.hpp"
#include "uniCell.hpp"
#include "uniCells.hpp"

namespace hms {


template<>
class MeshTraits<UniMesh>
{
public:
	using VertexType = Vector2s;
	using EdgeType   = UniEdge;
	using EdgesType  = UniEdges;
	using CellType   = UniCell;
	using CellsType  = UniCells;
	using SizeType   = const Array2i&;
};



class UniMesh : public StructMeshBase<UniMesh>
{
public:
	using Traits = MeshTraits<UniMesh>;
	
private:
	Array2i m_size {0,0};
	Array2s m_diff {1,1};
	Vector2s m_origin {0,0};

public:
	UniMesh() = default;
	UniMesh(
		Array2i size,
		Array2s diff,
		Vector2s origin = {0,0}
	);
	UniMesh(
		Index nCellsX,
		Index nCellsY,
		scalar dx,
		scalar dy,
		Vector2s origin = {0,0}
	);


	auto dx    () const -> scalar;
	auto dy    () const -> scalar;
	auto diff  () const -> const Array2s&;
	auto origin() const -> const Vector2s&;

private:
	auto nCellsXImp() const -> Index;
	auto nCellsYImp() const -> Index;

	auto sizeImp() const -> SizeType;

	auto vertexImp(Index) const -> Vector2s;

	auto domainAreaImp    () const -> scalar;

	friend MeshBase;
	friend StructMeshBase;
};

} // end namespace hms

#endif